package main

import (
	"fmt"
	"os"
	"strings"

	"warnmonitor/controllers"
	"warnmonitor/core"
	"warnmonitor/db"

	"github.com/astaxie/beego"
	"github.com/codegangsta/cli"
)

const (
	Author      = "secondriver"
	Email       = "secondriver@yeah.net"
	Appname     = "warnmonitor"
	Description = "警报监视通知服务"
	Copyright   = "Copyright 2015 secondriver"
	Version     = "v1.0.0"
)

const (
	API_PATH = "api_path"
)

var (
	ApiPath string = "/monitor"
)

func init() {
	if v := beego.AppConfig.String(API_PATH); v != "" {
		if !strings.HasPrefix(v, "/") {
			v = "/" + v
		}
		v = strings.TrimSuffix(v, "/")
		ApiPath = v
	}
}

func main() {
	//全局设定
	cli.HelpFlag.Usage = "帮助信息"
	cli.VersionFlag.Usage = "查看版本信息"

	//Cli应用
	app := cli.NewApp()
	app.Name = Appname
	app.Usage = Description
	app.Authors = []cli.Author{
		cli.Author{Name: Author, Email: Email},
	}
	app.Version = Version
	app.Copyright = Copyright

	app.CommandNotFound = func(c *cli.Context, command string) {
		fmt.Fprintf(c.App.Writer, "没有命令 '%v' 的帮助信息\n", command)
		cli.ShowCommandHelp(c, "")
	}

	//隐藏默认的帮助
	app.HideHelp = true

	//全局可选项
	app.Flags = []cli.Flag{
		cli.BoolTFlag{
			Name:  "verbose,V",
			Usage: "打印详细信息",
		},
		cli.StringFlag{
			Name:  "key, k",
			Usage: "加密使用的密钥",
		},
	}

	//命令集
	app.Commands = []cli.Command{
		cli.Command{
			Name:    "help",
			Aliases: []string{"h"},
			Usage:   "查看所有命令或指定命令帮助信息(help command)",
			Action: func(c *cli.Context) {
				args := c.Args()
				if args.Present() {
					cli.ShowCommandHelp(c, args.First())
				} else {
					cli.ShowAppHelp(c)
				}
			},
		},
		cli.Command{
			Name:    "run",
			Aliases: []string{"start", "go"},
			Usage:   "启动 warnmonitor web 服务",
			Flags: []cli.Flag{
				cli.BoolFlag{
					Name:  "rebuild,r",
					Usage: "开启数据库表重建",
				},
				cli.BoolFlag{
					Name:  "drop,d",
					Usage: "删除表后重建表",
				},
			},
			Action: func(c *cli.Context) {
				rebuild := c.Bool("rebuild")
				drop := c.Bool("drop")
				verbose := c.GlobalBool("verbose")
				//重建数据表
				if rebuild {
					err := db.ReBuildDb(drop, verbose)
					if err != nil {
						beego.Error(err)
						os.Exit(1)
					}
				}
				//初始化邮件服务
				key := c.GlobalString("key")
				core.InitEmailConfigInfo(key)
				//注册控制器
				beego.Router(ApiPath, &controllers.MonitorController{})
				beego.Run()
			},
		},
		cli.Command{
			Name:  "gen",
			Usage: "加密系统配置文件中的关键信息",
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "data, d",
					Usage: "加密的数据(*)",
				},
				cli.StringFlag{
					Name:  "aligorthm, a",
					Usage: fmt.Sprintf("加密算法(%s)(*)", strings.Join(core.Aligorthms, ",")),
				},
			},
			Action: func(c *cli.Context) {
				key := c.GlobalString("key")
				if len(key) < 4 {
					fmt.Println("key(" + key + ") too short, not less than 4 chars.")
					cli.ShowCommandHelp(c, c.Command.Name)
				}
				data := c.String("data")
				if data == "" {
					fmt.Println("data(" + data + ") cant not empty.")
					cli.ShowCommandHelp(c, c.Command.Name)
				}
				aligorthm := c.String("aligorthm")
				if aligorthm == "" {
					fmt.Println("aligorthm(" + aligorthm + ") cant not empty.")
					cli.ShowCommandHelp(c, c.Command.Name)
				}
				cipher, err := core.Encrypt(data, key, aligorthm)
				if err == nil {
					fmt.Printf("Data: %s \nKey：%s\nCipherText: %s\nConfig Use :%s\n", data, key, cipher, aligorthm+core.CipherTextSeparator+cipher)
				} else {
					fmt.Println(err.Error())
					cli.ShowCommandHelp(c, c.Command.Name)
				}
			},
		},
	}
	app.Run(os.Args)
}
